#include "StdAfx.h"
#include "u_i.h"


u_i::u_i(void)
{
}
u_i::u_i(double Rn,double Ic,double C, double w):rscjprops(Rn,Ic,C,w),utobj(Rn,Ic,C,0,0,0,w,0.01){
	this->Iac=0;
	this->iac=0;
	this->Imin=0;
	this->imin=0;
	this->Imax=5.0*Ic;
	this->imax=5;
	this->deltai=0.01;
	this->deltaI=0.01*Ic;
	this->h=0.01;
	this->filename="data";
}
u_i::u_i(double betac , double omega):rscjprops(betac,omega),utobj(betac,0,0,0,omega,0.01){
	this->Iac=0;
	this->iac=0;
	this->imax=5;
	this->Imax=-1;
	this->imin=0;
	this->Imin=-1;
	this->deltai=0.01;
	this->deltaI=-1;
	this->h=0.01;
	this->filename="data";
}
void u_i::work(){
	I.clear();
	U.clear();
	I.resize(0);
	U.resize(0);

	int n=2*((imax-imin)/deltai)+4;
	I.reserve(n);
	U.reserve(n);
	//I.resize(n);
	//U.resize(n);
	I.push_back(0);
	if(!normalized){
			utobj.setIac(Iac);
		U.push_back(calcU(0,0));
	int i=0;
	while(I[i]<Imax){
		++i;
		I.push_back(I[i-1]+deltaI);
		U.push_back(calcU(I[i],U[i-1]));
	}
	while(I[i]>Imin){
		++i;
		I.push_back(I[i-1]-deltaI);
		U.push_back(calcU(I[i],U[i-1]));
	}
	while(I[i]<0){
		++i;
		I.push_back(I[i-1]+deltaI);
		U.push_back(calcU(I[i],U[i-1]));
	}

	}else{
		utobj.setiac(iac);
		U.push_back(calcu(0,0));
	int i=0;
	while(I[i]<imax){
		++i;
		I.push_back(I[i-1]+deltai);
		U.push_back(calcu(I[i],U[i-1]));
	}
	while(I[i]>imin){
		++i;
		I.push_back(I[i-1]-deltai);
		U.push_back(calcu(I[i],U[i-1]));
	}
	while(I[i]<0){
		++i;
		I.push_back(I[i-1]+deltai);
		U.push_back(calcu(I[i],U[i-1]));
	}
		
	}
	//write();

}

double u_i::calcu(double i,double u){
	double U1=0;
		utobj.seth(h);
		utobj.setbetac(this->betac);
		utobj.setomega(this->omega);
		utobj.setiac(this->iac);
		utobj.setidc(i);
		utobj.setu0(u);
	utobj.work();
	U1=utobj.getu();
	return U1;
}


double u_i::calcU(double i,double u){
	double U1=0;
	double err=2;
	double smaxtemp;
	bool running=true;
	while(err>1 && running){
		utobj.seth(h);
		utobj.setIdc(i);
		utobj.setU0(u);
	utobj.setsmax(smax);
	utobj.work();
	U1=utobj.getU();
	err=utobj.getuerr()/(0.005+U1*0.005);
	smaxtemp=smax*(err/0.9);
	if(smaxtemp>50 && smaxtemp<1000){
		smax=smaxtemp;
	}else if(smaxtemp<=50){
		smax=50;
		running=false;
	}else if(smaxtemp>=1000){
		running=false;
	smax=1000;
	}
	}
	return U1;
}


void u_i::write(){
	
	std::fstream datei;
	datei.open(filename, std::ios::out);
	if(normalized){
		datei<<"Betac="<<betac<<std::endl;
		datei<<"Omega="<<omega<<std::endl;
		datei<<"Iac="<<iac<<std::endl;
	}else{
		datei<<"Betac="<<betac<<std::endl;
		datei<<"Omega="<<omega<<std::endl;
		datei<<"Omegac="<<wc<<std::endl;
		datei<<"Rn="<<Rn<<"Ohm"<<std::endl;
		datei<<"C="<<C<<"F"<<std::endl;
		datei<<"Ic="<<Ic<<"A"<<std::endl;
		datei<<"Iac="<<Iac<<"A"<<std::endl;
	}
	int n=I.size();
	for(int i=0;i<n;i++){
		datei<<I[i]<<" "<<U[i]<<std::endl;
	}
	datei.close();
}
u_i::~u_i(void)
{
}

void u_i::setimax(double imax){
	this->normalized=true;
	this->imax=imax;
	this->Imax=-1;
}
void u_i::setImax(double Imax){
	this->normalized=false;
	this->Imax=Imax;
	if(Ic>0){
		this->imax=Imax/Ic;
	}
}
void u_i::setimin(double imin){
	this->normalized=true;
	this->imin=imin;
	this->Imin=-1;
}
void u_i::setImin(double Imin){
	this->normalized=false;
	this->Imin=Imin;
	if(Ic>0){
		this->imin=Imin/Ic;
	}
}
void u_i::setDeltai(double Deltai){
	this->normalized=true;
	this->deltai=Deltai;
	this->deltaI=-1;
}
void u_i::setDeltaI(double DeltaI){
	this->normalized=false;
	this->deltaI=DeltaI;
	if(Ic>0){
		this->deltai=DeltaI/Ic;
	}
}
void u_i::setsmax(double smax){
	this->smax=smax;
	this->utobj.setsmax(smax);
}
void u_i::setfilename(std::string name){
this->filename=name;

}

double u_i::getimin(){
	return imin;
}
double u_i::getImin(){
	return Imin;
}
double u_i::getimax(){
	return imax;
}
double u_i::getImax(){
	return Imax;
}
double u_i::getDeltai(){
	return deltai;
}
double u_i::getDeltaI(){
	return Imax;
}
double u_i::getsmax(){
	
	return utobj.getsmax();
}


std::string u_i::getfilename(){
	return this->filename;
}